package gang.org.springframework.framework.annotation;

import gang.org.springframework.boot.condition.GangOnBeanCondition;
import gang.org.springframework.framework.factory.GangConfigurableListableBeanFactory;
import gang.org.springframework.framework.io.GangResourceLoader;
import gang.org.springframework.framework.metadata.GangAnnotatedTypeMetadata;
import gang.org.springframework.framework.support.GangBeanDefinitionRegistry;
import gang.org.springframework.framework.util.GangClassUtils;

//control + option + command 删除无引用类
public class GangConditionEvaluator {

    private final GangConditionContextImpl context;


    /**
     * 业务意义
     * 1）初始化自定义context
     * 2）TODO o2, o3
     * @param  registry 该类指向BeanFactory -> GangConfigurableListableBeanFactory
     * */
    public GangConditionEvaluator(GangBeanDefinitionRegistry registry, Object o2, Object o3){
        this.context = new GangConditionContextImpl(registry, null,null);
    }


    /**
     * 业务意义
     * TODO 业务意义
     * @param metadata 方法描述类，可以把它定义为元类，E.g
     * ************************************************************************
     *                 metadata = SimpleMethodMetadata
     *                      >methodName = "mvcResourceUrlProvider"
     *                      >declaringClassName = "*.GangResourceUrlProvider"
     * ************************************************************************
     * */
    public boolean shouldSkip(GangAnnotatedTypeMetadata metadata, Object phase){

        //TODO 场景一

        //TODO 场景二

        /*
         * 场景三 TODO
         * 1）hardcode 在此处理
         * 2）强调获取到方法上的注解
         * 3）举例E.g
         * **********************************************************************
         * 类名：*.WebMvcAutoConfiguration
         * 方法：@ConditionalOnMissingBean
         *      public InternalResourceViewResource defaultViewResolver(){}
         *
         *      @ConditionalOnMissingBean -> @Conditional -> @OnBeanCondition extend FilteringSpringBootCondition implement Condition > 执行matches
         * */
        GangCondition condition = new GangOnBeanCondition();
        condition.matches(this.context, null);
        return  false;
    }

    public static class GangConditionContextImpl implements GangConditionContext{

        private final GangBeanDefinitionRegistry registry;

        private final GangConfigurableListableBeanFactory beanFactory;

        //TODO
        private final Object environment;

        private final GangResourceLoader resourceLoader;

        private final ClassLoader classLoader;

        public GangConditionContextImpl(GangBeanDefinitionRegistry registry,
                                        Object environment,
                                        GangResourceLoader resourceLoader) {
            this.registry = registry;
            this.beanFactory = deduceBeanFactory(registry);
            this.environment = environment;
            this.resourceLoader = resourceLoader;
            this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
        }


        @Override
        public GangBeanDefinitionRegistry getRegistry() {
            return null;
        }

        @Override
        public GangConfigurableListableBeanFactory getBeanFactory() {
            return this.beanFactory;
        }

        @Override
        public Object getEnvironment() {
            return null;
        }

        @Override
        public GangResourceLoader getResourceLoader() {
            return null;
        }

        @Override
        public ClassLoader getClassLoader() {
            return this.classLoader;
        }


        public GangConfigurableListableBeanFactory deduceBeanFactory(GangBeanDefinitionRegistry registry){
            //场景一
            if (registry instanceof GangConfigurableListableBeanFactory) {
                return (GangConfigurableListableBeanFactory) registry;
            }
            //TODO 场景二
            return null;
        }

        public ClassLoader deduceClassLoader(GangResourceLoader resourceLoader, GangConfigurableListableBeanFactory beanFactory){
            //TODO 场景一

            //场景二
            if (beanFactory != null) {
                return beanFactory.getBeanClassLoader();
            }
            return GangClassUtils.getDefaultClassLoader();
        }
    }
}
